import { Configuration } from 'webpack'
import { merge } from 'webpack-merge'
import baseConfig from './webpack.base'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import path from 'path'
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'
import TerserPlugin from 'terser-webpack-plugin'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const glob = require('glob')
// 注意这里的引用是{ PurgeCSSPlugin }，npm上官方的引入是错误的。
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')

const prodConfig: Configuration = merge(baseConfig, {
  mode: 'production', // 生产模式,
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash:8].css', // 抽离css的输出目录和名称
      chunkFilename: '[name].[contenthash:8].css'
    }),
    // 添加 BundleAnalyzerPlugin
    new BundleAnalyzerPlugin({
      analyzerMode: 'static', // 生成静态HTML报告
      openAnalyzer: false,    // 不自动打开浏览器
      reportFilename: path.resolve(__dirname, `../analyze/report.html`), // 指定报告输出路径
      generateStatsFile: true, // 生成stats.json文件
      statsFilename: path.resolve(__dirname, `../analyze/stats.json`), // 指定stats.json输出路径
    }),
    new PurgeCSSPlugin({
      paths: glob.sync(`${path.join(__dirname, '../src')}/**/*`, {
        nodir: true
      }),
      // 用 only 来指定 purgecss-webpack-plugin 的入口
      // https://github.com/FullHuman/purgecss/tree/main/packages/purgecss-webpack-plugin
      only: ['dist'],
      safelist: {
        standard: [/^ant-/] // 过滤以ant-开头的类名，哪怕没用到也不删除
      }
    }),
  ],
  optimization: {
    // 减少入口文件打包的体积，运行时代码会独立抽离成一个runtime的文件
    runtimeChunk: {
      name: 'mainifels'
    },

    minimize: true, // 开启terser
    minimizer: [
      new CssMinimizerPlugin(), // 压缩css
      new TerserPlugin({
        parallel: true, // 开启多线程压缩
        extractComments: false, // 是否将注释剥离到单独文件，默认是true
        terserOptions: {
          output: {
            comments: false,
            ecma: 5
          },
          sourceMap: true,
          mangle: true,
          compress: {
            ecma: 5,
            keep_fargs: false,
            pure_getters: true,
            hoist_funs: true,
            pure_funcs: [
              'console.log',
              'classCallCheck',
              '_classCallCheck',
              '_possibleConstructorReturn',
              'Object.freeze',
              'invariant',
              'warning'
            ] // 删除console.log
          }
        }
      })
    ],
    splitChunks: {
      // include all types of chunks 支持异步和非异步共享chunk
      chunks: 'all',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      // 分隔代码
      cacheGroups: {
        vendors: {
          // 提取node_modules代码
          test: /node_modules/, // 只匹配node_modules里面的模块
          // name: 'vendors', // 提取文件命名为vendors,js后缀和chunkhash会自动加，可以不要定义固定的name
          minChunks: 1, // 只要使用一次就提取出来
          chunks: 'initial', // 只提取初始化就能获取到的模块,不管异步的
          minSize: 0, // 提取代码体积大于0就提取出来
          enforce: true,
          reuseExistingChunk: true,
          priority: 10 // 提取优先级为1
        },
        commons: {
          // 提取页面公共代码
          name: 'commons', // 提取文件命名为commons
          minChunks: 2, // 只要使用两次就提取出来
          chunks: 'initial', // 只提取初始化就能获取到的模块,不管异步的
          priority: 0, // 优先级
          enforce: true,
          reuseExistingChunk: true,
          minSize: 0 // 提取代码体积大于0就提取出来
        },
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true
        }
      }
    }
  },
  performance: {
    hints: false,
    maxAssetSize: 4000000, // 整数类型（以字节为单位）
    maxEntrypointSize: 5000000 // 整数类型（以字节为单位）
  }

})
export default prodConfig
